import 'package:dio/dio.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:testlzhu/common/login/login_utils.dart';
import 'package:testlzhu/data/net/error_entity.dart';
import 'base_entity.dart';
import 'http_config.dart';
import 'http_method.dart';
import 'package:common_utils/src/log_util.dart';

class HttpManager {
  static final HttpManager _shared = HttpManager._internal();

  factory HttpManager() => _shared;



  Dio? dio;

  HttpManager._internal() {
    if (null == dio) {
      BaseOptions options = BaseOptions(
          contentType: Headers.jsonContentType,
          responseType: ResponseType.json,
          receiveDataWhenStatusError: false,
          connectTimeout: HttpConfig.ConnectTimeout,
          receiveTimeout: HttpConfig.ReceiveTimeout);
      dio = Dio(options);
    }
  }

//  添加拦截器
  HttpManager addIntercept(Interceptor interceptor) {
    dio!.interceptors.add(interceptor);
    return this;
  }

  //设置BaseUrl
  HttpManager setBaseUrl(String baseUrl) {
    dio!.options.baseUrl = baseUrl;
    return this;
  }

  // 设置连接超时
  HttpManager setConnectTimout(int connectTimeout) {
    dio!.options.connectTimeout = connectTimeout;
    return this;
  }

//  设置响应超时
  HttpManager setReceiveTimeout(int receiveTimeout) {
    dio!.options.receiveTimeout = receiveTimeout;
    return this;
  }

  //设置返回成功的code值，默认为1
  setSuccessCode(int successCode) {
    BaseEntity.STATUS_OK = successCode;
  }


  Future request<T>(
      {required HTTPMethod method,
      required String url,
      Map<String, dynamic>? params,
      required data,
      String? baseUrl,
      Map<String, dynamic>? headers,
      required Function(T) success,
       Function(ErrorEntity)? error}) async {
    try {
      if (baseUrl != null) {
        if (baseUrl.isNotEmpty) {
          dio!.options.baseUrl = baseUrl;
        }
      }
      if (null != headers && headers.isNotEmpty) {
        dio!.options.headers.addAll(headers);
      }
      params ??= {};

      var response = await dio!.request(
        url,
        queryParameters: params,
        data: data,
        options: Options(method: hTTPMethodValues[method]),
      );
      LogUtil.e("onResponse--$response");
      if (null != response) {
        BaseEntity<T> entity = BaseEntity<T>.fromJson(response.data);
        if (entity.code == BaseEntity.STATUS_OK) {
          success(entity.data as T);
        } else {
          error!(ErrorEntity(code: entity.code, message: entity.msg));
          LogUtil.e("onError${entity.code},${entity.msg}");
        }
      } else {
        error!(ErrorEntity(code: -1, message: "未知错误！"));
        LogUtil.e('未知错误');
      }
    } on DioError catch (e) {
      error!(createErrorEntity(e));
      LogUtil.e(e);
    } on TypeError catch (e){
      error!(ErrorEntity(code: -1, message: e.toString()));
      LogUtil.e(e);
    }
    EasyLoading.dismiss();
  }

  Future? get<T>(
      {required String url, Map<String, dynamic>? params, String? baseUrl, Map<String, dynamic>? headers, required Function(T) success, required Function(ErrorEntity) error}) {
    request(method: HTTPMethod.GET, url: url, params: params, baseUrl: baseUrl, data: {}, headers: headers, success: success, error: error);
  }

  Future? post<T>(
      {required String url,
      String? baseUrl,
      Map<String, dynamic>? headers,
      data,
      required Function(T) success,
      required Function(ErrorEntity) error}) {
    request(method: HTTPMethod.POST, url: url, params: {}, baseUrl: baseUrl, data: data, headers: headers, success: success, error: error);
  }

  Future? put<T>(
      {required String url,
      Map<String, dynamic>? params,
      String? baseUrl,
      Map<String, dynamic>? headers,
      data,
      required Function(T) success,
      required Function(ErrorEntity) error}) {
    request(method: HTTPMethod.PUT, url: url, params: params, baseUrl: baseUrl, data: data, headers: headers, success: success, error: error);
  }

  Future? delete<T>(
      {required String url,
      required Map<String, dynamic> params,
      required String baseUrl,
      Map<String, dynamic>? headers,
      data,
      required Function(T) success,
      required Function(ErrorEntity) error}) {
    request(method: HTTPMethod.DELETE, url: url, params: params, baseUrl: baseUrl, data: data, headers: headers, success: success, error: error);
  }

  Future? patch<T>(
      {required String url,
      required Map<String, dynamic> params,
      String baseUrl = "",
      Map<String, dynamic>? headers,
      data,
      required Function(T) success,
      required Function(ErrorEntity) error}) {
    request(method: HTTPMethod.PATCH, url: url, params: params, baseUrl: baseUrl, data: data, headers: headers, success: success, error: error);
  }

  ErrorEntity createErrorEntity(DioError e) {
    switch (e.type) {
      case DioErrorType.cancel:
        return ErrorEntity(code: -1, message: "请求取消！");
      case DioErrorType.connectTimeout:
        return ErrorEntity(code: -1, message: "连接超时!");
      case DioErrorType.sendTimeout:
        return ErrorEntity(code: -1, message: "发送超时！");
      case DioErrorType.receiveTimeout:
        return ErrorEntity(code: -1, message: "响应超时！");
      case DioErrorType.response:
        try {
          int errCode = e.response!.statusCode!;
          String? errMsg = e.response!.statusMessage;
          return ErrorEntity(code: errCode, message: errMsg!);
        } on Exception {
          return ErrorEntity(code: -1, message: "未知错误！");
        }
      default:
        return ErrorEntity(code: -1, message: e.message);
    }
  }
}
